package com.ywd.platform.netty.jt080.po;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * JT808协议消息头
 */

/**
 * JT808协议消息头
 * 消息体属性结构（2字节，16位）：
 * 位  15  14  13  12  11  10  9   8   7   6   5   4   3   2   1   0
 *    保留位       分包  加密方式  版本标识  消息体长度(10位)
 */
@Accessors(chain=true)
@Data
public class JT808Header {

    // 消息体属性位掩码
    private static final int BODY_LENGTH_MASK = 0x03FF;  // 低10位：消息体长度
    private static final int VERSION_FLAG_MASK = 0x0400; // 第10位：版本标识
    private static final int ENCRYPTION_MASK = 0x1C00;   // 第11-13位：加密方式
    private static final int SUB_PACKAGE_MASK = 0x2000;  // 第14位：分包标志
    private static final int RESERVED_MASK = 0xC000;     // 第15位：保留位

    // 加密方式常量
    public static final int ENCRYPTION_NONE = 0;     // 不加密
    public static final int ENCRYPTION_RSA = 1;      // RSA加密
    public static final int ENCRYPTION_AES = 2;      // AES加密
    public static final int ENCRYPTION_RESERVED = 3; // 保留

    private int msgId;            // 消息ID (2字节)

    private int msgBodyProps;     // 消息体属性 (2字节)

    private int version;          // 协议版本号 (1字节)

    private String terminalPhone; // 终端手机号 (10字节BCD码)

    private int flowId;           // 消息流水号 (2字节)

    private int totalPackage;     // 总包数(分包时使用)
    private int packageNo;        // 包序号(分包时使用)

    // 构造函数
    public JT808Header() {
        // 默认值
        this.msgBodyProps = 0;
        this.version = 1;
    }

    public JT808Header(int msgId, String terminalPhone, int flowId) {
        this();
        this.msgId = msgId;
        this.terminalPhone = terminalPhone;
        this.flowId = flowId;
    }

    /**
     * 获取消息体长度
     */
    public int getMsgBodyLength() {
        return msgBodyProps & BODY_LENGTH_MASK;
    }

    /**
     * 设置消息体长度
     * @param length 消息体长度 (0-1023)
     */
    public void setMsgBodyLength(int length) {
        if (length < 0 || length > 1023) {
            throw new IllegalArgumentException("消息体长度必须在0-1023之间");
        }
        // 清除原来的长度位，设置新的长度
        msgBodyProps = (msgBodyProps & ~BODY_LENGTH_MASK) | (length & BODY_LENGTH_MASK);
    }

    /**
     * 是否包含版本标识
     */
    public boolean hasVersionFlag() {
        return (msgBodyProps & VERSION_FLAG_MASK) != 0;
    }

    /**
     * 设置版本标识
     * @param hasVersion 是否包含版本标识
     */
    public void setVersionFlag(boolean hasVersion) {
        if (hasVersion) {
            msgBodyProps |= VERSION_FLAG_MASK;
        } else {
            msgBodyProps &= ~VERSION_FLAG_MASK;
        }
    }

    /**
     * 获取加密方式
     * @return 0-不加密, 1-RSA加密, 2-AES加密, 3-保留
     */
    public int getEncryptionType() {
        return (msgBodyProps & ENCRYPTION_MASK) >> 11;
    }

    /**
     * 设置加密方式
     * @param encryptionType 0-不加密, 1-RSA加密, 2-AES加密, 3-保留
     */
    public void setEncryptionType(int encryptionType) {
        if (encryptionType < 0 || encryptionType > 3) {
            throw new IllegalArgumentException("加密方式必须在0-3之间");
        }
        // 清除原来的加密位，设置新的加密方式
        msgBodyProps = (msgBodyProps & ~ENCRYPTION_MASK) | ((encryptionType << 11) & ENCRYPTION_MASK);
    }

    /**
     * 是否包含分包
     */
    public boolean isHasSubPackage() {
        return (msgBodyProps & SUB_PACKAGE_MASK) != 0;
    }

    /**
     * 设置分包标志
     * @param hasSubPackage 是否包含分包
     */
    public void setHasSubPackage(boolean hasSubPackage) {
        if (hasSubPackage) {
            msgBodyProps |= SUB_PACKAGE_MASK;
        } else {
            msgBodyProps &= ~SUB_PACKAGE_MASK;
        }
    }

    /**
     * 获取保留位
     */
    public int getReservedBits() {
        return (msgBodyProps & RESERVED_MASK) >> 14;
    }

    /**
     * 设置保留位
     * @param reservedBits 保留位值 (0-3)
     */
    public void setReservedBits(int reservedBits) {
        if (reservedBits < 0 || reservedBits > 3) {
            throw new IllegalArgumentException("保留位必须在0-3之间");
        }
        // 清除原来的保留位，设置新的保留位
        msgBodyProps = (msgBodyProps & ~RESERVED_MASK) | ((reservedBits << 14) & RESERVED_MASK);
    }

    /**
     * 设置分包信息
     */
    public void setPackageInfo(int total, int no) {
        this.totalPackage = total;
        this.packageNo = no;
        setHasSubPackage(true);
    }

    /**
     * 获取完整的消息体属性值
     */
    public int getMsgBodyProps() {
        return msgBodyProps & 0xFFFF;
    }

    /**
     * 设置完整的消息体属性值
     */
    public void setMsgBodyProps(int msgBodyProps) {
        this.msgBodyProps = msgBodyProps & 0xFFFF; // 确保只有低16位有效
    }


    public void setVersion(int version) {
        this.version = version;
        setVersionFlag(version > 0); // 自动设置版本标识
    }

    @Override
    public String toString() {
        return "JT808Header{" +
                "msgId=0x" + Integer.toHexString(msgId) +
                ", msgBodyProps=0x" + Integer.toHexString(msgBodyProps) +
                ", version=" + version +
                ", terminalPhone='" + terminalPhone + '\'' +
                ", flowId=" + flowId +
                ", totalPackage=" + totalPackage +
                ", packageNo=" + packageNo +
                ", msgBodyLength=" + getMsgBodyLength() +
                ", hasVersionFlag=" + hasVersionFlag() +
                ", encryptionType=" + getEncryptionType() +
                ", hasSubPackage=" + isHasSubPackage() +
                ", reservedBits=" + getReservedBits() +
                '}';
    }
}
